package JUC;

// Q：（手写算法）用三个线程，线程“1”，“2”， “3”，顺序打印字母A-Z，输出结果是1A、2B、3C、1D 2E… ？

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ConditionDemo3 {

    static char c = 'A';

    static class Resource{
        int num = 1;

        Lock lock = new ReentrantLock();
        Condition c1 = lock.newCondition();
        Condition c2 = lock.newCondition();
        Condition c3 = lock.newCondition();

        private void print1() throws InterruptedException {
            lock.lock();
            try {
                while (num != 1){
                    c1.await();
                }
                System.out.println(Thread.currentThread().getName() +
                        c++);
                num = 2;
                c2.signal();
            } catch (Exception e){
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }

        private void print2() throws InterruptedException {
            lock.lock();
            try {
                while (num != 2){
                    c2.await();
                }
                System.out.println(Thread.currentThread().getName() +
                        c++);
                num = 3;
                c3.signal();
            } catch (Exception e){
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }

        private void print3() throws InterruptedException {
            lock.lock();
            try {
                while (num != 3){
                    c3.await();
                }
                System.out.println(Thread.currentThread().getName() +
                        c++);
                num = 1;
                c1.signal();
            } catch (Exception e){
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }

    public static void main(String[] args) {
        Resource resource = new Resource();

        new Thread(()->{
            for (int i = 0; i < 9; i++) {
                try {
                    resource.print1();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "1").start();

        new Thread(()->{
            for (int i = 0; i < 9; i++) {
                try {
                    resource.print2();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "2").start();

        new Thread(()->{
            for (int i = 0; i < 8; i++) {
                try {
                    resource.print3();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "3").start();
    }
}
